/*
 * circlebuff.h
 *
 *  Created on: 2023年6月29日
 *      Author: mcealt_DS
 */

#ifndef CIRCLE_BUFFER_H_
#define CIRCLE_BUFFER_H_

// Get the standard include types
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

// <h> Circular Buffer Configuration

// <o CIRCULAR_BUFFER_LEN_MAX> Max Buffer Length
// <0-256:1>
// <i> Default: 5
#define CIRCULAR_BUFFER_LEN_MAX  4096

// -----------------------------------------------------------------------------
// Structures and Types
// -----------------------------------------------------------------------------
typedef struct Buffer {
  uint16_t head;
  uint16_t count;
  uint16_t size;
  bool (*callback)(const struct Buffer *buffer, uint8_t data);
  uint8_t *data;
} Buffer_t;

/**
 * Pointer to a buffer overflow callback function.
 * @param buffer Pointer to the buffer structure being overflowed.
 * @param data Pointer to the item being considered for removal from the buffer
 * on overflow.
 * @return True to discard the buffer item being considered for removal
 * (default behavior) and false for nothing to be discarded from the buffer.
 */
typedef bool (*BufferOverflowCallback_t)(const Buffer_t *buffer, uint8_t data);

// -----------------------------------------------------------------------------
// Standard Buffer Functions
// -----------------------------------------------------------------------------
/**
 * Function to initialize a buffer structure with the given size. Note that this
 * size must be less than the CIRCULAR_BUFFER_LEN_MAX define.
 * @param buffer A pointer to the buffer structure to initialize
 * @param size The number of entries we want to allow you to store in this buffer
 * @return Returns true if we were able to initialize the buffer and false
 * otherwise.
 */
bool bufferInit(Buffer_t *buffer, uint16_t size);

/**
 * Add the specified data pointer to the end of the buffer. If the buffer is
 * full, the oldest bufferd item will be replaced by default. Register an
 * overflow callback to change this default behavior.
 * @param buffer The buffer to add the item to.
 * @param data The pointer object to store in the buffer.
 * @return Returns true if the data was stored and false otherwise.
 */
bool bufferAdd(Buffer_t *buffer, uint8_t data);

/**
 * Specify a callback to be called upon buffer overflow. The oldest bufferd item
 * being considered for removal on buffer overflow is provided by this callback.
 * @param buffer The buffer to specify an overflow callback for.
 * @param callback The callback to be called on buffer overflow. If callback is
 * NULL, no callback will be issued on buffer overflow.
 * @return Return true if a callback will be issued on buffer overflow and
 * false otherwise.
 */
bool bufferOverflow(Buffer_t *buffer, BufferOverflowCallback_t callback);

/**
 * Return a pointer to the head of the buffer without removing that item.
 * @param buffer The buffer to peek at the item from.
 * @return Returns a pointer to the data that is at the head of the buffer. If
 * the buffer is empty this value will be NULL. It's worth noting that NULL can
 * be a valid buffer value.
 */
uint8_t *bufferPeek(Buffer_t *buffer);

/**
 * Remove an item from the head of the buffer and return its pointer.
 * @param buffer The buffer to remove the item from.
 * @return Returns a pointer to the data that was at the head of the buffer. If
 * the buffer is empty this value will be NULL. It's worth noting that NULL can
 * also be a valid stored pointer.
 */
uint8_t *bufferRemove(Buffer_t *buffer);

/**
 * Determine if the given buffer is empty.
 * @param buffer The buffer to check the status of.
 * @return Returns true if the buffer is empty and false otherwise.
 */
bool bufferIsEmpty(Buffer_t *buffer);

/**
 * Determine if the given buffer is full.
 * @param buffer The buffer to check the status of.
 * @return Returns true if the buffer is full and false otherwise.
 */
bool bufferIsFull(Buffer_t *buffer);


//buffer 输出
void DS_circleBuffer(uint8_t *buff, uint16_t len);


#endif /* CIRCLE_BUFFER_H_ */
